package cn.ug.pay.web.controller;

import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.Order;
import cn.ug.bean.base.Page;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.core.SerializeObjectError;
import cn.ug.core.ensure.Ensure;
import cn.ug.core.login.LoginHelper;
import cn.ug.enums.ExtractGoldStatusEnum;
import cn.ug.enums.RateKeyEnum;
import cn.ug.feign.MemberUserService;
import cn.ug.feign.ProcessTemplateService;
import cn.ug.feign.ProductService;
import cn.ug.feign.RateSettingsService;
import cn.ug.member.bean.response.MemberUserBean;
import cn.ug.member.mq.MemberPasswordStatusMQ;
import cn.ug.mq.DelayMessagePostProcessor;
import cn.ug.pay.bean.request.ExtractionGoldOtherBean;
import cn.ug.pay.bean.request.ExtractionGoldPayBean;
import cn.ug.pay.bean.response.ExtractGoldFindBean;
import cn.ug.pay.bean.response.ExtractGoldUserStatisticsBean;
import cn.ug.pay.bean.status.CommonConstants;
import cn.ug.pay.mapper.entity.PayTbill;
import cn.ug.pay.service.ExtractionGoldService;
import cn.ug.pay.service.PayTbillService;
import cn.ug.product.bean.response.ProductFindBean;
import cn.ug.util.ExportExcelUtil;
import cn.ug.util.UF;
import cn.ug.web.controller.BaseController;
import cn.ug.web.controller.ExportExcelController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;

import static cn.ug.config.QueueName.QUEUE_MEMBER_PASSWORD_STATUS_DELAY;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * 提金控制器
 */
@RestController
@RequestMapping("extractGold")
public class ExtractionGoldController extends BaseController {

    @Autowired
    private ExtractionGoldService extractionGoldService;

    @Resource
    private MemberUserService memberUserService;

    @Autowired
    private RateSettingsService rateSettingsService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Resource
    private ProductService productService;

    @Resource
    private ProcessTemplateService processTemplateService;

    @Resource
    private PayTbillService payTbillService;
    /**
     * 提金订单查询接口
     * @param type 1快递 2门店
     * @param orderNo
     * @param productName
     * @param loginName
     * @param minGram
     * @param maxGram
     * @param addTimeMinString
     * @param addTimeMaxString
     * @param order
     * @return
     */
    @RequestMapping(value = "list",method = GET)
    public SerializeObject<ExtractGoldFindBean> queryList(Order order, Page page, Integer type, String orderNo,
                                                          String  productName, String loginName,
                                                          Integer minGram, Integer maxGram,
                                                          String addTimeMinString, String addTimeMaxString,Integer status,String shopName){
        LocalDateTime addTimeMin = null;
        LocalDateTime addTimeMax = null;
        if(StringUtils.isNotBlank(addTimeMinString)) {
            addTimeMin = UF.getDate(addTimeMinString);
        }
        if(StringUtils.isNotBlank(addTimeMaxString)) {
            addTimeMax = UF.getDate(addTimeMaxString);
        }
        if (type == null){
            return new SerializeObject(ResultType.ERROR,"00000002");
        }

        DataTable<ExtractGoldFindBean> extractGoldFindBeanDataTable = extractionGoldService.query(order.getOrder(), order.getSort(),page.getPageNum(),
                page.getPageSize(),type,orderNo,productName,loginName,minGram,maxGram,addTimeMin,addTimeMax,status,shopName);
        return new SerializeObject(ResultType.NORMAL,extractGoldFindBeanDataTable);
    }


    /**
     * 关闭订单
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/close/order", method = POST)
    public SerializeObject closeOrder(@RequestHeader String accessToken, ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo())){
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.closeOrder(submit);
    }

    /**
     * 查看备注信息
     *
     * @param accessToken
     * @return
     */
    @RequestMapping(value = "/find/remark", method = GET)
    public SerializeObject findRemark(@RequestHeader String accessToken, ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo())){
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.findRemark(submit.getOrderNo(),submit.getType());
    }

    /**
     * 备注订单
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/remark/update", method = POST)
    public SerializeObject remarkOrder(@RequestHeader String accessToken, ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo()) || StringUtils.isBlank(submit.getRemark())){
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.remarkOrder(submit);
    }

    /**
     * 订单发货
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/delivery", method = POST)
    public SerializeObject orderDelivery(@RequestHeader String accessToken, ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo()) || StringUtils.isBlank(submit.getLogisticsNo())) {
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.orderDelivery(submit);
    }

    /**
     * 订单跟踪
     */
    @RequestMapping(value = "/track", method = GET)
    public SerializeObject orderTrack(ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo())) {
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.orderTrack(submit.getOrderNo());
    }


    /**
     * 查看订单详情
     * @return
     */
    @RequestMapping(value = "/find/order", method = GET)
    public SerializeObject findOrder(ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo()) || submit.getType() == null){
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.findOrder(submit.getOrderNo(),submit.getType());
    }


    /**
     * 门店提金  审核-以及完成
     *
     * @param accessToken
     * @param submit
     * @return
     */
    @RequestMapping(value = "/audit", method = POST)
    public SerializeObject audit(@RequestHeader String accessToken, ExtractionGoldOtherBean submit) {
        if (StringUtils.isBlank(submit.getOrderNo())){
            return new SerializeObject(ResultType.ERROR,"00000002");
        }
        return extractionGoldService.extractionSucceed(submit.getOrderNo(),submit.getType(),submit.getStatus());
    }

    /**
     * 查看用户统计列表
     * @return
     */
    @RequestMapping(value = "/find/uesr/statistics", method = GET)
    public SerializeObject findUesrStatistics(Page page,String memberName, String mobile,
                                              Integer minGram, Integer maxGram) {
        DataTable<ExtractGoldUserStatisticsBean> resultList = extractionGoldService.findUserStatistics(page.getPageNum(),
                page.getPageSize(),memberName,mobile,minGram,maxGram);
        return new SerializeObject(ResultType.NORMAL,resultList);
    }


    /**
     * 查看用户明细
     * @return
     */
    @RequestMapping(value = "/queryDetail", method = GET)
    public SerializeObject queryDetail(Page page,String memberId) {
        DataTable<ExtractGoldFindBean> resultList = extractionGoldService.queryDetail(page.getPageNum(),
                page.getPageSize(),memberId);
        return new SerializeObject(ResultType.NORMAL,resultList);
    }


    /**
     * 导出列表导出
     * @param order
     * @param page
     * @param type
     * @param orderNo
     * @param productName
     * @param loginName
     * @param minGram
     * @param maxGram
     * @param addTimeMinString
     * @param addTimeMaxString
     * @param response
     */
    @GetMapping(value = "/list/export")
    public void queryForExport(Order order, Page page, Integer type, String orderNo,
                               String  productName, String loginName,
                               Integer minGram, Integer maxGram,
                               String addTimeMinString, String addTimeMaxString,Integer status,String shopName,HttpServletResponse response){
        LocalDateTime addTimeMin = null;
        LocalDateTime addTimeMax = null;
        if(StringUtils.isNotBlank(addTimeMinString)) {
            addTimeMin = UF.getDate(addTimeMinString);
        }
        if(StringUtils.isNotBlank(addTimeMaxString)) {
            addTimeMax = UF.getDate(addTimeMaxString);
        }
        DataTable<ExtractGoldFindBean> extractGoldFindBeanDataTable = extractionGoldService.query(order.getOrder(), order.getSort(),1,
                Integer.MAX_VALUE,type,orderNo,productName,loginName,minGram,maxGram,addTimeMin,addTimeMax,status,null);

        String fileName = "提金订单管理";
        String[] columnNames = { "序号", "提金订单流水号","所提提单编号", "用户账号", "商品名称", "商品克重（克）", "提金申请时间","提金订单状态","加工费（元）","快递运费（元）","共计支付费用（元）"};
        String[] columns = {"index",  "orderNo", "tbillNo", "loginName", "productName", "gram", "addTimeString","statusMark","processingFee","courierFee","actualAmount"};
        int index = 1;
        for (ExtractGoldFindBean bean : extractGoldFindBeanDataTable.getDataList()) {
            bean.setIndex(index);
            index++;
            bean.setStatusMark(ExtractGoldStatusEnum.getByStatus(bean.getStatus()));
        }
        ExportExcelController<ExtractGoldFindBean> export = new ExportExcelController<>();
        export.exportExcel(fileName, fileName, columnNames, columns, extractGoldFindBeanDataTable.getDataList(), response, ExportExcelUtil.EXCEL_FILE_2003);
    }

    /**
     * 导出用户统计列表
     * @return
     */
    @RequestMapping(value = "/find/uesr/export", method = GET)
    public void findUesrExport(Page page,String memberName, String mobile,
                                              Integer minGram, Integer maxGram,HttpServletResponse response) {
        DataTable<ExtractGoldUserStatisticsBean> resultList = extractionGoldService.findUserStatistics(page.getPageNum(),
                page.getPageSize(),memberName,mobile,minGram,maxGram);

        String fileName = "提金用户管理";
        String[] columnNames = { "序号", "手机号","姓名", "累计提金总克重（克）"};
        String[] columns = {"index",  "mobile", "memberName", "totalGram"};
        int index = 1;
        for (ExtractGoldUserStatisticsBean bean : resultList.getDataList()) {
            bean.setIndex(index);
            index++;
        }
        ExportExcelController<ExtractGoldUserStatisticsBean> export = new ExportExcelController<>();
        export.exportExcel(fileName, fileName, columnNames, columns, resultList.getDataList(), response, ExportExcelUtil.EXCEL_FILE_2003);
    }


    /**
     * 导出用户明细
     * @return
     */
    @RequestMapping(value = "/queryDetail/export", method = GET)
    public void queryDetailExport(Page page,String memberId,HttpServletResponse response) {
        DataTable<ExtractGoldFindBean> resultList = extractionGoldService.queryDetail(page.getPageNum(),
                page.getPageSize(),memberId);

        String fileName = "提金用户管理";
        String[] columnNames = { "序号", "提金订单流水号","所提提单编号", "商品名称","商品克重（克）","提金方式","提金完成时间"};
        String[] columns = {"index",  "orderNo", "tbillNo", "productName","gram","statusMark","finalTime"};
        int index = 1;
        for (ExtractGoldFindBean bean : resultList.getDataList()) {
            bean.setIndex(index);
            bean.setStatusMark("快递提金");
            index++;
        }
        ExportExcelController<ExtractGoldFindBean> export = new ExportExcelController<>();
        export.exportExcel(fileName, fileName, columnNames, columns, resultList.getDataList(), response, ExportExcelUtil.EXCEL_FILE_2003);
    }

    /************************************************APP接口**********************************************************************************/
    /**
     * 查询提金手续费率信息
     * @return
     */
    @RequestMapping(value = "find/fee/{tbillNo}" , method = GET)
    public SerializeObject findFee(@PathVariable("tbillNo") String tbillNo) {
        if (StringUtils.isBlank(tbillNo)){
            return new SerializeObject(ResultType.NORMAL, "00000002");
        }
        return extractionGoldService.findFee(tbillNo);
    }

    /**
     * 提金-确认支付申请
     * @param accessToken
     * @param requestParams
     * @return
     */
    @RequestMapping(value = "pay" , method = POST)
    public SerializeObject pay(@RequestHeader String accessToken,ExtractionGoldPayBean requestParams) {
        String memberId = LoginHelper.getLoginId();
        if (StringUtils.isBlank(memberId)) {
            return new SerializeObjectError("00000102");
        }
        //参数验证
        Ensure.that(requestParams.getPayPassword()).isNull("170020454");
        Ensure.that(requestParams.getPayPassword().length() == 6).isFalse("17000408");  //验证交易密码长度是否正确
        if (requestParams.getType() == 8){
            Ensure.that(requestParams.getAddress()).isNull("17002047");
        }
        Ensure.that(requestParams.getCellphone()).isNull("17002048");
        Ensure.that(requestParams.getFullname()).isNull("17002049");
        Ensure.that(requestParams.getTbillNo()).isNull("17002050");
        Ensure.that(requestParams.getType()).isNull("17000414");
        Ensure.that(requestParams.getWay()).isNull("17000401");
        Ensure.that(CommonConstants.PayWay.getName(requestParams.getWay())).isNull("17000406");

        PayTbill payTbill = payTbillService.selectByOrderNO(requestParams.getTbillNo());
        if (payTbill == null) {
            return new SerializeObjectError("00000003");
        }

        SerializeObject<ProductFindBean> productResult = productService.queryProductById(payTbill.getProductId());
        if (productResult != null) {
            //获取加工费信息
            SerializeObject serializeObject = processTemplateService.find(productResult.getData().getProcessId());
            if (serializeObject != null && serializeObject.getCode() == 200) {
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(serializeObject.getData()));
                BigDecimal processCost = jsonObject.getBigDecimal("processCost");
                int disCount = jsonObject.getInteger("disCount");
                BigDecimal cost = processCost.multiply(new BigDecimal(disCount)).divide(new BigDecimal(100));
                requestParams.setProcessingFee(cost.setScale(4, BigDecimal.ROUND_HALF_UP));
            }
        }

        //获取运费信息
        if (requestParams.getType() == 8){
            SerializeObject resultRep = rateSettingsService.get(RateKeyEnum.FREIGHT.getKey());
            if (resultRep != null && resultRep.getData() != null) {
                JSONObject json = JSON.parseObject(JSONObject.toJSONString(resultRep.getData()));
                requestParams.setCourierFee(json.getBigDecimal("fee"));
                requestParams.setActualAmount(requestParams.getCourierFee().add(requestParams.getProcessingFee()));
            }
        }else {
            requestParams.setActualAmount(requestParams.getProcessingFee());
        }


        // 交易密码验证
        SerializeObject obj = memberUserService.validatePayPassword(memberId, requestParams.getPayPassword());
        if (null == obj || obj.getCode() != ResultType.NORMAL) {
            SerializeObject paramBean = rateSettingsService.get(RateKeyEnum.TRADE_PASSWORD.getKey());
            if (paramBean != null && paramBean.getData() != null) {
                JSONObject json = JSON.parseObject(JSONObject.toJSONString(paramBean.getData()));
                int isLimited = json.getIntValue("isLimited");
                int wrongTimes = json.getIntValue("wrongTimes");
                int minutes = json.getIntValue("minutes");
                if (isLimited == 1) {
                    SerializeObject<MemberUserBean> memberBean = memberUserService.findById(memberId);
                    if (null == memberBean || memberBean.getData() == null) {
                        return new SerializeObjectError("00000102");
                    }
                    MemberUserBean memberUserBean = memberBean.getData();
                    if (isLimited == 1 && memberUserBean.getTrdpassdStatus() == 1) {
                        SerializeObjectError result = new SerializeObjectError<>("17002034");
                        String msg = String.format(result.getMsg(), wrongTimes, minutes);
                        result.setMsg(msg);
                        return result;
                    }
                    int actualWrongTimes = memberUserBean.getTrdpassdWrongTimes();
                    actualWrongTimes++;
                    int status = 0;
                    if (wrongTimes <= actualWrongTimes) {
                        status = 1;
                    }
                    memberUserService.modifyWrongTimes(memberUserBean.getId(), 2, actualWrongTimes, status);
                    if (wrongTimes <= actualWrongTimes) {
                        MemberPasswordStatusMQ mq = new MemberPasswordStatusMQ();
                        mq.setMemberId(memberUserBean.getId());
                        mq.setType(2);
                        amqpTemplate.convertAndSend(QUEUE_MEMBER_PASSWORD_STATUS_DELAY, mq, new DelayMessagePostProcessor(minutes * 60 * 1000));

                        SerializeObjectError result = new SerializeObjectError<>("17002034");
                        String msg = String.format(result.getMsg(), wrongTimes, minutes);
                        result.setMsg(msg);
                        return result;
                    }
                }
            }
            info("交易密码验证失败。 memberId = " + memberId);
            return obj;
        }
        //提金申请
        return extractionGoldService.pay(requestParams,memberId);
    }

    /**
     * 我的提金订单列表
     * @param accessToken
     * @param page
     * @param status  1-已预约， 2-待收货， 3-已取消， 4-已完成
     * @return
     */
    @RequestMapping(value = "findMyList" , method = GET)
    private SerializeObject findMyList(@RequestHeader String accessToken,Integer status,Page page){
        String memberId = LoginHelper.getLoginId();
        if (StringUtils.isBlank(memberId)) {
            return new SerializeObjectError("00000102");
        }
        return new SerializeObject(ResultType.NORMAL,extractionGoldService.findList(memberId,page.getPageNum(),page.getPageSize(),status));
    }

    @RequestMapping(value = "findDetail" , method = GET)
    private SerializeObject findDetail(String orderNo,Integer type){
        return extractionGoldService.findDetail(orderNo,type);
    }

    /**
     * 阅读提金订单
     * @param accessToken
     * @param orderNo
     * @param type   提金类型：1快递 2门店
     * @return
     */
    @RequestMapping(value = "read" , method = POST)
    private SerializeObject read(@RequestHeader String accessToken,String orderNo,Integer type){
        String memberId = LoginHelper.getLoginId();
        if (StringUtils.isBlank(memberId)) {
            return new SerializeObjectError("00000102");
        }
        extractionGoldService.read(orderNo,type);
        return new SerializeObject(ResultType.NORMAL);
    }
}
